package com.jlf.controller.engine;

import com.jlf.controller.engine.entity.domain.SchemaDomainDetail;
import com.jlf.controller.engine.entity.domain.SchemaDomainInput;
import com.jlf.core.annotation.restful.controller.RestfulController;
import com.jlf.core.annotation.restful.method.RestfulDelete;
import com.jlf.core.annotation.restful.method.RestfulGet;
import com.jlf.core.annotation.restful.method.RestfulPost;
import com.jlf.core.annotation.restful.method.RestfulPut;
import com.jlf.core.engine.domain.SchemaDomainDO;
import com.jlf.core.engine.domain.SchemaFieldDO;
import com.jlf.core.engine.domain.SchemaIndexDO;
import com.jlf.core.engine.persistence.SchemaDomainPersistence;
import com.jlf.core.engine.persistence.SchemaFieldPersistence;
import com.jlf.core.engine.persistence.SchemaIndexPersistence;
import com.jlf.core.engine.query.SchemaDomainQueryInput;
import com.jlf.core.engine.server.SchemaDomainServer;
import com.jlf.core.error.exception.NoObjectException;
import com.jlf.core.output.ListResultWrapper;
import com.jlf.core.server.entity.EditRecordWrapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;


/**
 * 领域定义的接口控制器
 *
 * @author wujr
 * 2023/7/7
 * @version 1.0
 * 【变更历史】
 * [wujr 2023/7/7 1.0 新增]
 */
@Slf4j
@Tag(name = "模型领域管理接口")
@RestfulController(path = "/rest/jlf/core/engine/schema/domains", name = "模型领域管理接口", domainClass = SchemaDomainDO.class)
@RequiredArgsConstructor
public class SchemaDomainController {
    private final SchemaDomainServer schemaDomainServer;
    private final SchemaDomainPersistence schemaDomainPersistence;
    private final SchemaFieldPersistence schemaFieldPersistence;
    private final SchemaIndexPersistence schemaIndexPersistence;

    @RestfulPost(code = "addSchemaDomain", name = "新增模型领域")
    public SchemaDomainDO add(@Valid @RequestBody SchemaDomainInput input) throws Exception{
        SchemaDomainDO record = input.to();
        return schemaDomainServer.add(record);
    }

    @RestfulPut(code = "editSchemaDomain", name = "编辑模型领域", path = "/{domainId}")
    public SchemaDomainDO editSchemaDomain(@PathVariable("domainId") Long domainId,
                                           @Valid @RequestBody SchemaDomainInput input) throws Exception{
        SchemaDomainDO original = schemaDomainPersistence.getById(domainId);
        if (original == null){
            log.info("编辑模型领域：{}，该模型不存在", domainId);
            throw new NoObjectException(SchemaDomainDO.class, "模型领域");
        }
        SchemaDomainDO record = input.to();
        EditRecordWrapper<SchemaDomainDO> wrapper = new EditRecordWrapper<>();
        wrapper.setOriginal(original);
        wrapper.setRecord(record);
        schemaDomainServer.edit(wrapper);
        return wrapper.getRecord();
    }

    @RestfulDelete(code = "deleteSchemaDomain", name = "删除模型领域", path = "/{domainId}")
    public void deleteSchemaDomain(@PathVariable("domainId") Long domainId) throws Exception{
        SchemaDomainDO record = schemaDomainPersistence.getById(domainId);
        if (record == null){
            log.info("删除模型领域：{}，该模型不存在", domainId);
            throw new NoObjectException(SchemaDomainDO.class, "模型领域");
        }
        schemaDomainServer.delete(record);
    }

    @RestfulGet(code = "querySchemaDomain", name = "查询模型领域")
    public ListResultWrapper<SchemaDomainDO> querySchemaDomain(SchemaDomainQueryInput input,
                                                               @RequestParam(value = "pageNo", required = false, defaultValue = "1") int pageNo,
                                                               @RequestParam(value = "pageSize", required = false, defaultValue = "50") int pageSize){
        return schemaDomainServer.query(input, pageNo, pageSize);
    }

    @RestfulGet(code = "viewSchemaDomain", name = "查看模型领域详情", path = "/{domainId}")
    public SchemaDomainDetail viewSchemaDomain(@PathVariable("domainId") Long domainId) throws Exception {
        SchemaDomainDO record = schemaDomainPersistence.getById(domainId);
        if (record == null){
            log.info("查看模型领域详情：{}，该模型不存在", domainId);
            throw new NoObjectException(SchemaDomainDO.class, "模型领域");
        }

        SchemaDomainDetail output = new SchemaDomainDetail(record);
        List<SchemaFieldDO> schemaFields = schemaFieldPersistence.loadByDomain(record.getDomainCode(), null);
        List<SchemaIndexDO> schemaIndexes = schemaIndexPersistence.loadByDomain(record.getDomainCode());

        for (SchemaFieldDO schemaField : schemaFields){
            output.addField(schemaField);
        }
        for (SchemaIndexDO schemaIndex : schemaIndexes){
            output.addIndex(schemaIndex);
        }
        return output;
    }
}
